package com.cloud.nacosConfigLoad;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;

/**
 * 热部署管理类，结合文件监控和 Bean 注入
 * 发现类加载器不生效
 */
@Component
public class HotDeploymentManager {

    private final BeanManager beanManager;

    // 注入 BeanManager，用于处理 Bean 的销毁和重新注入
    @Autowired
    public HotDeploymentManager(BeanManager beanManager) {
        this.beanManager = beanManager;
    }

    /**
     * 监控指定目录下的 `.class` 文件变化，并在文件变化时重新加载 Bean
     *
     * @param directoryPath 要监控的目录路径
     */
    public void monitorAndReloadBeans(String directoryPath) {
        // 创建文件监控对象
        ClassFileWatcher watcher = new ClassFileWatcher(directoryPath);

        // 启动监控，文件发生变化时调用回调方法
        watcher.startWatching(fileName -> {
            try {
                // 当 .class 文件变化时，动态加载类并创建实例
                String className = extractClassName(fileName); // 解析类名
                File classFile = new File(directoryPath, fileName);

                // 使用自定义类加载器加载 class 文件
                HotBeanClassLoader hotClassLoader = new HotBeanClassLoader(classFile);
                Class<?> clazz = hotClassLoader.loadClass(className); // 根据类名加载类
                Object newInstance = clazz.getDeclaredConstructor().newInstance(); // 创建新的类实例

                // Bean 名称根据类名生成，类名的最后一部分作为 Bean 名
                String beanName = className.substring(className.lastIndexOf('.') + 1);
                beanName = Character.toLowerCase(beanName.charAt(0)) + beanName.substring(1); // 首字母小写
                beanManager.reloadBean(beanName, newInstance); // 重新加载 Bean
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 从文件名提取类名
     *
     * @param fileName 文件名（如 A.class）
     * @return 完整的类名（如 com.cloud.load.demo.A）
     */
    private String extractClassName(String fileName) {
        // 根据文件路径解析出类名
        return "com.cloud.nacosConfigLoad.test." + fileName.replace(".class", "");
    }
}
